﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace Simulation.Framework
{
    public class ResManagerByNet : ManagerBehavior
    {
        private Dictionary<string, TextAsset> xmlCache = new Dictionary<string, TextAsset>();
        private Dictionary<string, TextAsset> jsonCache = new Dictionary<string, TextAsset>();
        private Dictionary<string, TextAsset> txtCache = new Dictionary<string, TextAsset>();
        private Dictionary<string, AudioClip> audioCache = new Dictionary<string, AudioClip>();
        private Dictionary<string, Texture> textureCache = new Dictionary<string, Texture>();
        private Dictionary<string, GameObject> gameObjectCache = new Dictionary<string, GameObject>();

        private List<string> xmlDownloadCache = new List<string>();
        private List<string> jsonDownloadCache = new List<string>();
        private List<string> txtDownloadCache = new List<string>();
        private List<string> audioDownloadCache = new List<string>();
        private List<string> textureDownloadCache = new List<string>();
        private List<string> gameObjectDownloadCache = new List<string>();

        #region override

        public override void Init()
        {
            jsonCache = new Dictionary<string, TextAsset>();
            xmlCache = new Dictionary<string, TextAsset>();
            txtCache = new Dictionary<string, TextAsset>();
            audioCache = new Dictionary<string, AudioClip>();
            gameObjectCache = new Dictionary<string, GameObject>();
            textureCache = new Dictionary<string, Texture>();

            xmlDownloadCache = new List<string>();
            jsonDownloadCache = new List<string>();
            txtDownloadCache = new List<string>();
            audioDownloadCache = new List<string>();
            textureDownloadCache = new List<string>();
            gameObjectDownloadCache = new List<string>();
        }

        public override void Clear()
        {
            ClearXmlCache();
            ClearJsonCache();
            ClearTxtCache();
            ClearAudioCache();
            ClearTextureCache();

            xmlCache = null;
            jsonCache = null;
            txtCache = null;
            audioCache = null;
            gameObjectCache = null;
            textureCache = null;

            xmlDownloadCache = null;
            jsonDownloadCache = null;
            txtDownloadCache = null;
            audioDownloadCache = null;
            textureDownloadCache = null;
            gameObjectDownloadCache = null;

            Resources.UnloadUnusedAssets();
            GC.Collect();
        }

        public override void Restar() { }

        #endregion

        #region xml

        public void LoadXml(string url, UnityAction<string> response)
        {
            if (xmlCache.ContainsKey(url))
                response?.Invoke(xmlCache[url].text);
            else
            {
                if (!xmlDownloadCache.Contains(url))
                    xmlDownloadCache.Add(url);
                SingleBehavior<HttpManager>.getInstance().DownloadTextAsset(url, (u, v) =>
                {
                    if (xmlDownloadCache.Contains(u))
                        xmlDownloadCache.Remove(u);

                    if (v != null) {
                        xmlCache[url] = v;
                        response?.Invoke(v.text);
                    }
                    else
                        response?.Invoke(string.Empty);
                });
            }
        }

        public void RemoveXml(string url)
        {
            if (xmlCache.ContainsKey(url))
            {
                xmlCache.Remove(url);
                Resources.UnloadUnusedAssets();
            }
            else
            {
                SingleBehavior<HttpManager>.getInstance().StopDownload(url);
                if (xmlDownloadCache.Contains(url))
                    xmlDownloadCache.Remove(url);
            }
        }

        public void ClearXmlCache()
        {
            if (xmlCache == null) return;
            xmlCache.Clear();
            Resources.UnloadUnusedAssets();

            if (xmlDownloadCache == null) return;
            for (int i = 0; i < xmlDownloadCache.Count; i++)
                SingleBehavior<HttpManager>.getInstance().StopDownload(xmlDownloadCache[i]);
            xmlDownloadCache.Clear();
        }

        #endregion

        #region json

        public void LoadJson(string url, UnityAction<string> response)
        {
            if (jsonCache.ContainsKey(url))
                response?.Invoke(jsonCache[url].text);
            else
            {
                if (!jsonDownloadCache.Contains(url))
                    jsonDownloadCache.Add(url);
                SingleBehavior<HttpManager>.getInstance().DownloadTextAsset(url, (u, v) =>
                {
                    if (jsonDownloadCache.Contains(u))
                        jsonDownloadCache.Remove(u);
                    if (v != null) {
                        jsonCache[url] = v;
                        response?.Invoke(v.text);
                    }
                    else
                        response?.Invoke(string.Empty);
                });
            }
        }

        public void RemoveJson(string url)
        {
            if (jsonCache.ContainsKey(url))
            {
                jsonCache.Remove(url);
                Resources.UnloadUnusedAssets();
            }
            else
            {
                SingleBehavior<HttpManager>.getInstance().StopDownload(url);
                if (jsonDownloadCache.Contains(url))
                    jsonDownloadCache.Remove(url);
            }
        }

        public void ClearJsonCache()
        {
            if (jsonCache == null) return;
            jsonCache.Clear();
            Resources.UnloadUnusedAssets();

            if (jsonDownloadCache == null) return;
            for (int i = 0; i < jsonDownloadCache.Count; i++)
                SingleBehavior<HttpManager>.getInstance().StopDownload(jsonDownloadCache[i]);
            jsonDownloadCache.Clear();
        }

        #endregion

        #region txt

        public void LoadTxt(string url, UnityAction<string> response)
        {
            if (txtCache.ContainsKey(url))
                response?.Invoke(txtCache[url].text);
            else
            {
                if (!txtDownloadCache.Contains(url))
                    txtDownloadCache.Add(url);
                SingleBehavior<HttpManager>.getInstance().DownloadTextAsset(url, (u, v) =>
                {
                    if (txtDownloadCache.Contains(u))
                        txtDownloadCache.Remove(u);
                    if (v != null){
                        txtCache[url] = v;
                        response?.Invoke(v.text);
                    }
                    else
                        response?.Invoke(string.Empty);
                });
            }
        }

        public void RemoveTxt(string url)
        {
            if (txtCache.ContainsKey(url))
            {
                txtCache.Remove(url);
                Resources.UnloadUnusedAssets();
            }
            else
            {
                SingleBehavior<HttpManager>.getInstance().StopDownload(url);
                if (txtDownloadCache.Contains(url))
                    txtDownloadCache.Remove(url);
            }
        }

        public void ClearTxtCache()
        {
            if (txtCache == null) return;
            txtCache.Clear();
            Resources.UnloadUnusedAssets();

            if (txtDownloadCache == null) return;
            for (int i = 0; i < txtDownloadCache.Count; i++)
                SingleBehavior<HttpManager>.getInstance().StopDownload(txtDownloadCache[i]);
            txtDownloadCache.Clear();
        }

        #endregion

        #region texture

        public void LoadTexture(string url, UnityAction<Texture> response)
        {
            if (textureCache.ContainsKey(url))
                response?.Invoke(textureCache[url]);
            else
            {
                if (!textureDownloadCache.Contains(url))
                    textureDownloadCache.Add(url);
                SingleBehavior<HttpManager>.getInstance().DownLoadTexture(url, (u, v) =>
                {
                    if (textureDownloadCache.Contains(u))
                        textureDownloadCache.Remove(u);
                    if (v != null)
                        textureCache[url] = v;
                    response?.Invoke(v);
                });
            }
        }

        public void RemoveTexture(string url)
        {
            if (textureCache.ContainsKey(url))
            {
                textureCache.Remove(url);
                Resources.UnloadUnusedAssets();
            }
            else
            {
                SingleBehavior<HttpManager>.getInstance().StopDownload(url);
                if (textureDownloadCache.Contains(url))
                    textureDownloadCache.Remove(url);
            }
        }

        public void ClearTextureCache()
        {
            if (textureCache == null) return;
            textureCache.Clear();
            Resources.UnloadUnusedAssets();

            if (textureDownloadCache == null) return;
            for (int i = 0; i < textureDownloadCache.Count; i++)
                SingleBehavior<HttpManager>.getInstance().StopDownload(textureDownloadCache[i]);
            textureDownloadCache.Clear();
        }

        #endregion

        #region audio

        public void LoadAudio(string url, UnityAction<AudioClip> response)
        {
            if (audioCache.ContainsKey(url))
                response?.Invoke(audioCache[url]);
            else
            {
                if (!audioDownloadCache.Contains(url))
                    audioDownloadCache.Add(url);
                SingleBehavior<HttpManager>.getInstance().DownLoadAudio(url, (u, v) =>
                {
                    if (audioDownloadCache.Contains(url))
                        audioDownloadCache.Remove(u);
                    if (v != null)
                        audioCache[url] = v;
                    response?.Invoke(v);
                });
            }
        }

        public void RemoveAudio(string url)
        {
            if (audioCache.ContainsKey(url))
            {
                audioCache.Remove(url);
                Resources.UnloadUnusedAssets();
            }
            else
            {
                SingleBehavior<HttpManager>.getInstance().StopDownload(url);
                if (audioDownloadCache.Contains(url))
                    audioDownloadCache.Remove(url);
            }
        }

        public void ClearAudioCache()
        {
            if (audioCache == null) return;
            audioCache.Clear();
            Resources.UnloadUnusedAssets();

            if (audioDownloadCache == null) return;
            for (int i = 0; i < audioDownloadCache.Count; i++)
                SingleBehavior<HttpManager>.getInstance().StopDownload(audioDownloadCache[i]);
            audioDownloadCache.Clear();
        }

        #endregion
    }
}